#include "hal.h"

BYTE READ_PORT_BYTE(PBYTE pbPort){
    REG BYTE bRes;
    __inbyte((WORD)(DWORD_PTR)pbPort, bRes);
    return bRes;
}

WORD READ_PORT_WORD(PWORD pwPort){
    REG WORD wRes;
    __inword((WORD)(DWORD_PTR)pwPort, wRes);
    return wRes;
}

DWORD READ_PORT_DWORD(PDWORD pdwPort){
    REG DWORD dwRes;
    __indword((WORD)(DWORD_PTR)pdwPort, dwRes);
    return dwRes;
}

VOID WRITE_PORT_BYTE(PBYTE pbPort, BYTE bValue){
    __outbyte((WORD)(DWORD_PTR)pbPort, bValue);
}

VOID WRITE_PORT_WORD(PWORD pwPort, WORD wValue){
    __outword((WORD)(DWORD_PTR)pwPort, wValue);
}

VOID WRITE_PORT_DWORD(PDWORD pdwPort, DWORD dwValue){
    __outdword((WORD)(DWORD_PTR)pdwPort, dwValue);
}

DWORD HalPciReadIoConfigByte(DWORD dwAddress, PBYTE pbResult, BYTE bOffset){
    *(PBYTE)&dwAddress = bOffset & 0xFC;
    __outdword(0xCF8, dwAddress);
    __inbyte(((WORD)bOffset & 3) | 0xCFC, *pbResult);
    return sizeof(BYTE);
}

DWORD HalPciReadIoConfigWord(DWORD dwAddress, PWORD pwResult, BYTE bOffset){
    *(PBYTE)&dwAddress = bOffset & 0xFC;
    __outdword(0xCF8, dwAddress);
    __inword(((WORD)bOffset & 3) | 0xCFC, *pwResult);
    return sizeof(WORD);
}

DWORD HalPciReadIoConfigDword(DWORD dwAddress, PDWORD pdwResult, BYTE bOffset){
    *(PBYTE)&dwAddress = bOffset & 0xFC;
    __outdword(0xCF8, dwAddress);
    __inword(0xCFC, *pdwResult);
    return sizeof(DWORD);
}

DWORD HalPciWriteIoConfigByte(DWORD dwAddress, BYTE bValue, BYTE bOffset){
    *(PBYTE)&dwAddress = bOffset & 0xFC;
    __outdword(0xCF8, dwAddress);
    __outbyte(((WORD)bOffset & 3) | 0xCFC, bValue);
    return sizeof(BYTE);
}

DWORD HalPciWriteIoConfigWord(DWORD dwAddress, WORD wValue, BYTE bOffset){
    *(PBYTE)&dwAddress = bOffset & 0xFC;
    __outdword(0xCF8, dwAddress);
    __outword(((WORD)bOffset & 3) | 0xCFC, wValue);
    return sizeof(BYTE);
}

DWORD HalPciWriteIoConfigDword(DWORD dwAddress, DWORD dwValue, BYTE bOffset){
    *(PBYTE)&dwAddress = bOffset & 0xFC;
    __outdword(0xCF8, dwAddress);
    __outdword(0xCFC, dwValue);
    return sizeof(BYTE);
}

DWORD HalPciReadMmConfigByte(DWORD_PTR dwAddress, PBYTE pbResult, BYTE bOffset){
    *pbResult = *(PBYTE)(dwAddress + bOffset);
    return sizeof(BYTE);
}

DWORD HalPciReadMmConfigWord(DWORD_PTR dwAddress, PWORD pwResult, BYTE bOffset){
    *pwResult = *(PWORD)(dwAddress + bOffset);
    return sizeof(WORD);
}

DWORD HalPciReadMmConfigDword(DWORD_PTR dwAddress, PDWORD pdwResult, BYTE bOffset){
    *pdwResult = *(PDWORD)(dwAddress + bOffset);
    return sizeof(DWORD);
}

DWORD HalPciWriteMmConfigByte(DWORD_PTR dwAddress, BYTE bValue, BYTE bOffset){
    *(PBYTE)(dwAddress + bOffset) = bValue;
    return sizeof(BYTE);
}

DWORD HalPciWriteMmConfigWord(DWORD_PTR dwAddress, WORD wValue, BYTE bOffset){
    *(PWORD)(dwAddress + bOffset) = wValue;
    return sizeof(WORD);
}

DWORD HalPciWriteMmConfigDword(DWORD_PTR dwAddress, DWORD dwValue, BYTE bOffset){
    *(PDWORD)(dwAddress + bOffset) = dwValue;
    return sizeof(DWORD);
}